package org.genuflex.utils
{
	import mx.utils.StringUtil;
	import mx.collections.ArrayCollection;
	import mx.utils.ObjectUtil;
	
	public class GenuflexDataFunctions
	{
		//Works with String and ArrayCollection
		public static function isNotEmpty(object : Object) : Boolean {		
			return (object != null && object.length > 0);
		}
		//Works with String and ArrayCollection
		public static function isEmpty(object : Object) : Boolean {		
				return (object == null || object.length == 0);
		}
		public static function findByID(collection : Object, id : int, idFieldName : String = "id") : Object {
			return findByValue(collection, id, idFieldName);
		}
		public static function findByValue(collection : Object, value : Object, fieldName : String) : Object {

			//Iterate through the collection looking for a match
			if (collection != null) {
				for each(var obj : Object in collection) {
					if (obj[fieldName] == value) {
						return obj;
					}
				}
			}
			
			return null;
		}

		public static function listByValue(collection : Object, value : Object, fieldName : String) : ArrayCollection {
			var matches : ArrayCollection = new ArrayCollection();
			
			//Iterate through the collection looking for a match
			if (collection != null) {
				for each(var obj : Object in collection) {
					if (obj[fieldName] == value) {
						matches.addItem(obj);
					}
				}
			}
			
			return matches;
		}
		
		// areSame - Not are they equal, but is it the same from a logical standpoint.  
		// is the id the same and the class the same?
		public static function areSame(objA : Object, objB :Object) : Boolean {
			var areSame : Boolean = false;
			var classInfoA : Object = null; 
			var classInfoB : Object = null; 							

			if (objA != null && objB != null) {
				classInfoA = ObjectUtil.getClassInfo(objA);
				classInfoB = ObjectUtil.getClassInfo(objB);

				if (objA.id == objB.id && classInfoA.name == classInfoB.name) {
					areSame = true;
				}
			}
			
			return areSame;
		}
		
		// buildIDList - Takes an array of objects and builds an array of their ids.
		public static function buildIDList(array : Array, idProperty : String = "id" ) : Array {
			var idList : Array = new Array();
			if (array != null) {
				for each(var obj : Object in array) {
					idList.push(obj[idProperty]);	
				}
			}
			return idList;
		}
		
		public static function removeFromArray(array : Object, item : Object) : void {
			if (array is ArrayCollection && array.getItemIndex(item) >=0) {
				array.removeItemAt(array.getItemIndex(item));
			}
			else if (array is Array && (array as Array).indexOf(item) >= 0) {
				delete array[(array as Array).indexOf(item)];
			}
		}
		
		public static function isSearchMatch(item : Object, fieldNames : Array, searchString : String) : Boolean {
			var fieldValue : Object;
			var fieldValueStr : String;
			
			//Drop search string to lower case
			searchString = searchString.toLowerCase();
			
			//Look for a match on all provided fields
			for each(var fieldName : String in fieldNames) {
				fieldValue = item[fieldName];
				
				//If a function was a return, fire it to get the actual value
				if (fieldValue is Function) {
					fieldValue = (fieldValue as Function).call(item);	
				}
				
				if (isNotEmpty(fieldValue)) {
					fieldValueStr = fieldValue.toString().toLowerCase();
					
					//If any part of the field matches, we have a hit
					if (fieldValueStr.indexOf(searchString) >= 0) {
						return true;
					}
				}	
			}
			
			return false;
		}
		
		// It is an extension of parseFloat that will return a zero instead of NaN
		public static function parseFloatWithDefault(str : String, defaultValue : Number = 0) : Number {
			var value : Number = parseFloat(str);
			
			if (isNaN(value)) {
				value = defaultValue;
			}
			
			return value;
		}
		
		public static function isEven(numValue : Number) : Boolean {
			return !(numValue%2); 
		}		
	}
}